package com.sad.jetpack.v1.datamodel.api.extension.engine;

import androidx.annotation.NonNull;

import com.sad.jetpack.v1.datamodel.api.IDataModelChainOutput;
import com.sad.jetpack.v1.datamodel.api.IDataModelProductEngine;
import com.sad.jetpack.v1.datamodel.api.IDataModelRequest;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public abstract class OkHttpEngine<RP> implements IDataModelProductEngine<RP> {
    @Override
    public void onEngineExecute(IDataModelRequest request, IDataModelChainOutput<RP> chainOutput) throws Exception {
        Request.Builder okhttpRequestBuilder=new Request.Builder();
        okhttpRequestBuilder.url(request.url());
        if (request.method()== IDataModelRequest.Method.GET){
            okhttpRequestBuilder=okhttpRequestBuilder.get();
        }
        if (request.headers()!=null){
            Iterator<Map.Entry<String, String>> iterator=request.headers().entrySet().iterator();
            while (iterator.hasNext()){
                Map.Entry<String,String> entityEntry=iterator.next();
                okhttpRequestBuilder.addHeader(entityEntry.getKey(),entityEntry.getValue());
            }
        }
        onResetOkhttpRequest(request,okhttpRequestBuilder);
        OkHttpClient.Builder builder=new OkHttpClient.Builder()
                .callTimeout(request.timeout(), TimeUnit.MILLISECONDS)
                .connectTimeout(request.timeout(), TimeUnit.MILLISECONDS)
                .readTimeout(request.timeout(), TimeUnit.MILLISECONDS)
                .writeTimeout(request.timeout(), TimeUnit.MILLISECONDS)
                .followRedirects(true);
        onResetOkhttpClient(request,builder);
        OkHttpClient okHttpClient=builder.build();
        okHttpClient.newCall(okhttpRequestBuilder.build())
                .enqueue(new Callback() {
                    @Override
                    public void onFailure(@NonNull Call call, @NonNull IOException e) {
                        if (chainOutput.exceptionListener()!=null){
                            chainOutput.exceptionListener().onDataObtainedException(request,e);
                        }
                    }

                    @Override
                    public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {

                        onHandleOkhttpResponse(request,response,chainOutput);
                    }
                });
    }
    public void onResetOkhttpClient(IDataModelRequest request, OkHttpClient.Builder builder){

    }
    public abstract void onResetOkhttpRequest(IDataModelRequest request, Request.Builder okhttpRequestBuilder);
    public abstract void onHandleOkhttpResponse(IDataModelRequest request, Response response, IDataModelChainOutput<RP> chainOutput) throws IOException;
}
